% visualize_buffer_lifetimes.m
% 绘制每个Buffer的生命周期图。

function fig = visualize_buffer_lifetimes(history, type_code_to_plot)
    
    fig = figure('Name', sprintf('Buffer 生命周期 (Cache Type %d)', type_code_to_plot));
    hold on;

    % 筛选出指定缓存类型的buffer
    buf_ids = keys(history.buffer_lifetimes);

    % =====================================================================
    % [Perf-Option] 控制显示规模：最小持续步数与Top-K（避免绘制过多条）
    % =====================================================================
    min_duration_steps = 5;   % 小于该持续长度的生命周期不绘制
    top_k_buffers = 200;      % 最多绘制的buffer数量（按总持续时长排序）

    % 预计算每个buffer在该类型上的总持续长度
    durations = zeros(1, numel(buf_ids));
    for i = 1:numel(buf_ids)
        bid = buf_ids{i};
        intervals = history.buffer_lifetimes(bid);
        dsum = 0;
        for j = 1:length(intervals)
            if intervals{j}{3} == type_code_to_plot
                dsum = dsum + (intervals{j}{2} - intervals{j}{1});
            end
        end
        durations(i) = dsum;
    end
    % 过滤掉总持续过短的buffer
    valid_idx = find(durations >= min_duration_steps);
    buf_ids = buf_ids(valid_idx);
    durations = durations(valid_idx);
    % 选择Top-K
    if numel(buf_ids) > top_k_buffers
        [~, order] = sort(durations, 'descend');
        order = order(1:top_k_buffers);
        buf_ids = buf_ids(order);
    end
    y_pos = 1;
    y_labels = {};
    
    for i = 1:length(buf_ids)
        buf_id = buf_ids{i};
        intervals = history.buffer_lifetimes(buf_id);
        
        % 检查此buffer是否曾在指定的type_code中出现
        is_in_type = false;
        for j = 1:length(intervals)
            if intervals{j}{3} == type_code_to_plot
                is_in_type = true;
                break;
            end
        end
        
        if is_in_type
            y_labels{end+1} = num2str(buf_id);
            for j = 1:length(intervals)
                interval = intervals{j};
                if interval{3} == type_code_to_plot
                    start_step = interval{1};
                    end_step = interval{2};
                    % 使用 patch 绘制一个水平条
                    patch([start_step, end_step, end_step, start_step], ...
                          [y_pos-0.4, y_pos-0.4, y_pos+0.4, y_pos+0.4], ...
                           'b', 'EdgeColor', 'k');
                end
            end
            y_pos = y_pos + 1;
        end
    end
    
    hold off;

    % 设置图表格式
    if ~isempty(y_labels)
        yticks(1:(y_pos-1));
        yticklabels(y_labels);
    end
    ylim([0, y_pos]);
    xlim([0, length(history.steps)]);
    title(sprintf('Buffer 生命周期 (Cache Type %d)', type_code_to_plot));
    xlabel('调度步骤 (Step)');
    ylabel('Buffer ID');
    grid on;
    set(gca, 'YDir','reverse'); % 将y轴反转，让ID从小到大排列

end